Enlarge picture with mousewheel scrolling

revision:


basic example

holiday
code:
            <div class="one">
                <img src="../images/1.jpg" id="zoomable" alt=holiday" width="50%" height="50%"/>
             </div>
            <style>
                .one img {display: block; max-width: 100%; width: 25vw; margin-inline: 3vw;}
                #zoomable{transition: transform 0.1s ease; max-width: 100%; height: auto; 
                    transform-origin: center;  }
            </style>
            <script>
                const img = document.getElementById('zoomable');
                let scale = 1;

                img.addEventListener('wheel', (e) => {
                    e.preventDefault(); // Prevent page scrolling

                    // Zoom in or out based on scroll direction
                    if (e.deltaY < 0) {
                        scale += 0.1; // Zoom in
                    } else {
                        scale -= 0.1; // Zoom out
                    }

                    // Optional: Limit min/max scale
                    scale = Math.min(Math.max(0.5, scale), 3);

                    img.style.transform = `scale(${scale})`;
                });
            </script>
        

move picture to center and zoom it

move mouse over picture to center it, zoom-in/out with mousewheel, click picture to close it

Hover to center zoom
code:
            <div class="two">
                <img id="zoomable1" src="../images/5a.jpg" class="zoom-on-hover" alt="Hover to center zoom">
            </div>
            <style>
                .two {display: flex; justify-content: flex-start; align-items: flex-start; height: 100vh; width: 40vw;}
                .two img {width: 30vw; margin: 4vw;}
                .zoom-on-hover.centered {position: fixed; top: 50%; left: 50%;transform: translate(-50%, -50%) scale(1); z-index: 1000;
                max-width: 50vw; max-height: 50vh; transition: transform .5s ease; cursor: zoom-in;}
            </style>
            <script>
                document.querySelectorAll('.zoom-on-hover').forEach(img => {
                    let originalStyle = {};
                    let scale = 1;
                    
                    // On mouseover: center the image
                    img.addEventListener('mouseenter', () => {
                        // Save original inline styles (optional but safe)
                        originalStyle = {
                            position: img.style.position,
                            top: img.style.top,
                            left: img.style.left,
                            transform: img.style.transform,
                            zIndex: img.style.zIndex
                        };
                        // Apply centered class
                        img.classList.add('centered');
                        scale = 1; // reset zoom each time
                        img.style.transform = 'translate(-50%, -50%) scale(1)';
                    });

                    // On mousewheel: zoom (only when centered)
                    img.addEventListener('wheel', (e) => {
                        if (!img.classList.contains('centered')) return;

                        e.preventDefault();
                        const delta = e.deltaY > 0 ? -0.1 : 0.1;
                        scale += delta;
                        scale = Math.min(Math.max(0.5, scale), 3);
                        img.style.transform = `translate(-50%, -50%) scale(${scale})`;
                    
                    });

                    // On click: return to original position
                    img.addEventListener('click', () => {
                        img.classList.remove('centered');
                        // Restore original inline styles (optional)
                        Object.assign(img.style, originalStyle);
                    });

                });
            </script> 
        

doubleclick pictures, center them, and zoom-in

doubleclick pictures to center them, zoom-in/out with mousewheel, click pictures to close them

holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
code:
        <div class="three">
            <figure><img class="zoomIt" src="../images/5a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/6.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/7.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/8.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/9.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/6a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/7a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/8a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/9a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/10.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/10a.jpg" alt=holiday" width="50%" height="50%"/></figure>
            <figure><img class="zoomIt" src="../images/11.jpg" alt=holiday" width="50%" height="50%"/></figure>
        </div>
        
        <style>
            .info{font-size: 1.2vw;}
            .three {position: relative; display: grid; grid-template-columns: repeat(5, 1fr); justify-content:center; gap: .1vw; }
            .zoomIt{width: 15vw; height: 30vh;}
            .zoomIt.centered {position: fixed; top: 50%; left: 50%;transform: translate(-50%, -50%) scale(1); z-index: 1000;  max-width: 30vw; max-height: 50vh; transition: transform .15s ease; cursor: zoom-in;}
        </style> 
        <script>
            document.querySelectorAll('.zoomIt').forEach(img => {
                let originalStyle = {};
                let scale = 1;
                
                // On dblclick: center the image
                img.addEventListener('dblclick', () => {
                    // Save original inline styles (optional but safe)
                    originalStyle = {
                        position: img.style.position,
                        top: img.style.top,
                        left: img.style.left,
                        transform: img.style.transform,
                        zIndex: img.style.zIndex
                    };

                    // Apply centered class
                    img.classList.add('centered');
                    scale = 1; // reset zoom each time
                    img.style.transform = 'translate(-50%, -50%) scale(1)';
                });

                // On mousewheel: zoom (only when centered)
                img.addEventListener('wheel', (e) => {
                    if (!img.classList.contains('centered')) return;

                    e.preventDefault();
                    const delta = e.deltaY > 0 ? -0.1 : 0.1;
                    scale += delta;
                    scale = Math.min(Math.max(0.5, scale), 5);
                    img.style.transform = `translate(-50%, -50%) scale(${scale})`;
                   
                });

                // On click: return to original position
                img.addEventListener('click', () => {
                    img.classList.remove('centered');
                    // Restore original inline styles (optional)
                    Object.assign(img.style, originalStyle);
                });

            });
        </script>
       
    

add drag-to-pan

doubleclick pictures to center them, zoom-in/out with mousewheel, drag them, click pictures to close them

holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
code:
            <div class="four">
                <figure><img class="zoom_It" src="../images/5a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/6.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/7.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/8.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/9.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/6a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/7a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/8a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/9a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/10.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/10a.jpg" alt=holiday" width="50%" height="50%"/></figure>
                <figure><img class="zoom_It" src="../images/11.jpg" alt=holiday" width="50%" height="50%"/></figure>
            </div>
            <style>
                .info{font-size: 1.2vw;}
                .four {position: relative; display: grid; grid-template-columns: repeat(5, 1fr); justify-content:center; gap: .1vw; }
                .zoom_It{width: 15vw; height: 30vh;}
                .zoom_It.centered {position: fixed; top: 50%; left: 50%;transform: translate(-50%, -50%) scale(1); z-index: 1000; max-width: 40vw; max-height: 60vh; transition: transform .15s ease; cursor: grab; ;}
                .zoom_It.centered.drag{cursor: grab;}
            </style> 
            <script>
                document.querySelectorAll('.zoom_It').forEach(img => {
                    let originalStyle = {};
                    let scale = 1;
                    let offsetX = 0, offsetY = 0; // pan offsets
                    let isDragging = false;
                    let startX, startY;
                    
                    // === Center on doubleclick ===
                    img.addEventListener('dblclick', () => {
                        originalStyle = {
                            position: img.style.position,
                            top: img.style.top,
                            left: img.style.left,
                            transform: img.style.transform,
                            zIndex: img.style.zIndex
                        };

                        img.classList.add('centered');
                        scale = 1;
                        offsetX = offsetY = 0;
                        updateTransform();
                    });

                    // === Zoom with scroll (only when centered) ===
                    img.addEventListener('wheel', (e) => {
                        if (!img.classList.contains('centered')) return;
                        e.preventDefault();

                        const zoomIntensity = 0.1;
                        const delta = e.deltaY > 0 ? -zoomIntensity : zoomIntensity;
                        scale += delta;
                        scale = Math.min(Math.max(0.5, scale), 5);
                        updateTransform();
                    });

                    // === Start drag ===
                    img.addEventListener('mousedown', (e) => {
                        if (!img.classList.contains('centered')) return;
                        e.preventDefault();
                        isDragging = true;
                        img.classList.add('drag');
                        startX = e.clientX - offsetX;
                        startY = e.clientY - offsetY;
                        img.style.cursor = 'grab';
                    });

                    // === Drag movement ===
                    window.addEventListener('mousemove', (e) => {
                        if (!isDragging || !img.classList.contains('centered')) return;
                        offsetX = e.clientX - startX;
                        offsetY = e.clientY - startY;
                        updateTransform();
                    });

                    // === End drag ===
                    window.addEventListener('mouseup', () => {
                        if (isDragging) {
                            isDragging = false;
                            img.classList.remove('drag');
                            img.style.cursor = 'grab';
                        }
                    });

                    // === Restore original position on click ===
                    img.addEventListener('click', () => {
                        // Only exit if not dragging (optional: you can force exit)
                        if (!isDragging) {
                        img.classList.remove('centered', 'drag');
                        Object.assign(img.style, originalStyle);
                        }
                    });

                    // === Helper: Apply transform ===
                    function updateTransform() {
                        img.style.transform = `translate(calc(-50% + ${offsetX}px), calc(-50% + ${offsetY}px)) scale(${scale})`;
                    }
                });

            </script>


        

pan a zoomed image

holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
holiday"
code:
            <div class="five">
                <div class="image-container"><img class="zoomImage" src="../images/5a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/6.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/7.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/8.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/9.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/6a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/7a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/8a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/9a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/10.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/10a.jpg" alt=holiday" width="50%" height="50%"/></div>
                <div class="image-container"><img class="zoomImage" src="../images/11.jpg" alt=holiday" width="50%" height="50%"/></div>
            </div>
            <style>
                .five{display: flex; flex-wrap: wrap; gap: 1.25vw; padding: 1.2vw;justify-content: center;}
                .image-container { width: 25vw; height: 40vh; overflow: hidden; border: 0.1vw solid #ccc; position: relative; cursor: grab;}
                .zoomImage{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.1s ease; user-select: none; /* We'll control scale/position via JS */ }
                .zoomImage.dragging {cursor: grabbing;}
            </style>  
            <script>
                // For each image container, attach zoom/pan behavior
                document.querySelectorAll('.image-container').forEach(container => {
                    const img = container.querySelector('.zoomImage');

                    let scale = 1;
                    let offsetX = 0;
                    let offsetY = 0;
                    let isDragging = false;
                    let startX, startY, startOffsetX, startOffsetY;

                    const minScale = 1;
                    const maxScale = 3;
                    const zoomIntensity = 0.1;

                    // Initial style
                    img.style.transform = 'translate(0,0) scale(1)';

                    // Mouse down to start drag
                    container.addEventListener('mousedown', (e) => {
                        if (e.button !== 0) return; // left click only
                        isDragging = true;
                        container.classList.add('dragging');
                        startX = e.clientX;
                        startY = e.clientY;
                        startOffsetX = offsetX;
                        startOffsetY = offsetY;
                        e.preventDefault();
                    });

                    // Mouse move = pan
                    window.addEventListener('mousemove', (e) => {
                        if (!isDragging) return;
                        offsetX = startOffsetX + (e.clientX - startX);
                        offsetY = startOffsetY + (e.clientY - startY);
                        applyTransform();
                    });

                    // Mouse up = stop drag
                    window.addEventListener('mouseup', () => {
                        isDragging = false;
                        container.classList.remove('dragging');
                    });

                    // Zoom with wheel
                    container.addEventListener('wheel', (e) => {
                        e.preventDefault();
                        const zoom = e.deltaY > 0 ? -zoomIntensity : zoomIntensity;
                        const newScale = Math.min(Math.max(scale + zoom, minScale), maxScale);
                        if (newScale === scale) return;

                        // Zoom toward mouse position inside container
                        const rect = container.getBoundingClientRect();
                        const mouseX = e.clientX - rect.left;
                        const mouseY = e.clientY - rect.top;

                        // Adjust offset so point under cursor stays fixed
                        offsetX = (mouseX - offsetX) * (newScale / scale) + offsetX - mouseX;
                        offsetY = (mouseY - offsetY) * (newScale / scale) + offsetY - mouseY;

                        scale = newScale;
                        applyTransform();
                    });

                    // Optional: double-click to reset
                    container.addEventListener('dblclick', () => {
                        scale = 1;
                        offsetX = 0;
                        offsetY = 0;
                        applyTransform();
                    });

                    function applyTransform() {
                        // Get container and natural image dimensions
                        const contWidth = container.clientWidth;
                        const contHeight = container.clientHeight;
                        const imgWidth = img.naturalWidth;
                        const imgHeight = img.naturalHeight;

                        // Max allowable offset (so image doesn't show empty space)
                        const maxOffsetX = (imgWidth * scale - contWidth) / 2;
                        const maxOffsetY = (imgHeight * scale - contHeight) / 2;

                        // Constrain panning
                        offsetX = Math.max(-maxOffsetX, Math.min(maxOffsetX, offsetX));
                        offsetY = Math.max(-maxOffsetY, Math.min(maxOffsetY, offsetY));

                        // Apply
                        img.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
                    }

                    // Initialize on load
                    if (img.complete) {
                        applyTransform();
                    } else {
                        img.onload = applyTransform;
                    }
                });
            </script>